home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / DOKICK.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  20KB  |  756 lines

  1. /*    SCCS Id: @(#)dokick.c    3.0    89/6/9
  2. /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include    "hack.h"
  6. #include    "eshk.h"
  7.  
  8. #define martial()    ((pl_character[0] == 'S' || pl_character[0] == 'P'))
  9.  
  10. static struct rm NEARDATA *maploc;
  11.  
  12. #ifdef KICK
  13.  
  14. # ifdef WORM
  15. extern boolean notonhead;
  16. # endif
  17.  
  18. static void FDECL(kickdmg, (struct monst *, BOOLEAN_P));
  19. static void FDECL(kick_monster, (int, int));
  20. static int FDECL(kick_object, (int, int));
  21. static char *NDECL(kickstr);
  22.  
  23. static struct obj NEARDATA *kickobj;
  24.  
  25. static void
  26. kickdmg(mon, clumsy)
  27. register struct monst *mon;
  28. register boolean clumsy;
  29. {
  30.     register int mdx, mdy;
  31.     register int dmg = (((uarmg && 
  32.                 uarmg->otyp == GAUNTLETS_OF_POWER) ? 
  33.                 25 : ACURR(A_STR) > 18 ? 18 : ACURR(A_STR))+
  34.                 ACURR(A_DEX)+ACURR(A_CON))/15;
  35.  
  36.     /* excessive wt affects dex, so it affects dmg */
  37.     if(clumsy) dmg = dmg/2;
  38.  
  39.     /* kicking a dragon or an elephant will not harm it */
  40.     if(thick_skinned(mon->data)) dmg = 0;
  41.     
  42.  
  43.     /* squeeze some guilt feelings... */
  44.     if(mon->mtame) {
  45. # ifdef SOUNDS
  46.         if (rn2(10)) yelp(mon);
  47.         else growl(mon); /* give them a moment's worry */
  48. # endif
  49.         mon->mtame--;
  50.         mon->mflee = mon->mtame ? 1 : 0;
  51. # ifdef HISX
  52.         mon->mfleetim = mon->mfleetim + (dmg ? rnd(dmg) : 1);
  53. # else
  54.         mon->mfleetim += (dmg ? rnd(dmg) : 1);
  55. # endif
  56.     }
  57.     
  58.     if (dmg)
  59.         mon->mhp -= (!martial() ? rnd(dmg) :
  60.             rnd(dmg)+rnd(ACURR(A_DEX)/2));  
  61.     if(mon->mhp < 1) {
  62.         (void) passive(mon, TRUE, 0, TRUE);
  63.         killed(mon);
  64.         return;
  65.     }
  66.     if(martial() && !bigmonst(mon->data) && !rn2(3) && mon->mcanmove) {
  67.             /* see if the monster has a place to move into */
  68.             mdx = mon->mx + u.dx;
  69.             mdy = mon->my + u.dy;
  70.             if(goodpos(mdx, mdy, mon->data)) {
  71.             kludge("%s reels from the blow.", Monnam(mon));
  72.             remove_monster(mon->mx, mon->my);
  73.             place_monster(mon, mdx, mdy);
  74.             pmon(mon);
  75.             set_apparxy(mon);
  76.             }
  77.     }
  78.     (void) passive(mon, FALSE, 1, TRUE);
  79.  
  80. /*    it is unchivalrous to attack the defenseless or from behind */
  81.     if (pl_character[0] == 'K' && u.ualigntyp == U_LAWFUL && 
  82.         u.ualign > -10 && (!mon->mcanmove || mon->msleep || mon->mflee))
  83.             adjalign(-1);
  84.  
  85. }
  86.  
  87. static void
  88. kick_monster(x, y)
  89. register int x, y;
  90. {
  91.     register boolean clumsy = FALSE;
  92.     register struct monst *mon = m_at(x, y);
  93.     register int i, j;
  94.  
  95.     if(special_case(mon)) return;
  96.     setmangry(mon);
  97. #ifdef POLYSELF
  98.     /* Kick attacks by kicking monsters are normal attacks, not special.
  99.      * If you have >1 kick attack, you get all of them.
  100.      */
  101.     if (attacktype(uasmon, AT_KICK)) {
  102.         schar tmp = find_roll_to_hit(mon);
  103.         for(i=0; i<NATTK; i++) {
  104.         int sum = 0;
  105.         if (uasmon->mattk[i].aatyp == AT_KICK && multi >= 0) {
  106.             /* check multi; maybe they had 2 kicks and the first */
  107.             /* was a kick against a floating eye */
  108.             j = 1;
  109.             if (tmp > rnd(20)) {
  110.             kludge("You kick %s.", mon_nam(mon));
  111.             sum = damageum(mon, &(uasmon->mattk[i]));
  112.             if (sum == 2)
  113.                 (void)passive(mon, 1, 0, TRUE);
  114.             else (void)passive(mon, sum, 1, TRUE);
  115.             } else {
  116.             missum(mon, &(uasmon->mattk[i]));
  117.             (void)passive(mon, 0, 1, TRUE);
  118.             }
  119.         }
  120.         }
  121.         return;
  122.     }
  123. #endif
  124.  
  125.     /* no need to check POLYSELF since only ghosts, which you can't turn */
  126.     /* into, are noncorporeal */
  127.     if(noncorporeal(mon->data)) {
  128.         Your("kick passes through!");
  129.         return;
  130.     }
  131.  
  132.     if(Levitation && !rn2(3) && verysmall(mon->data) &&
  133.        !is_flyer(mon->data)) {
  134.         pline("Floating in the air, you miss wildly!");
  135.         (void) passive(mon, FALSE, 1, TRUE);
  136.         return;
  137.     }
  138.  
  139.     i = abs(inv_weight());
  140.     j = weight_cap();
  141.  
  142.     if(i < (j*3)/10) {
  143.         if(!rn2((i < j/10) ? 2 : (i < j/5) ? 3 : 4)) {
  144.             if(martial() && !rn2(2)) goto doit;
  145.             Your("clumsy kick does no damage.");
  146.             (void) passive(mon, FALSE, 1, TRUE);
  147.             return;
  148.         }
  149.         if(i < j/10) clumsy = TRUE;
  150.         else if(!rn2((i < j/5) ? 2 : 3)) clumsy = TRUE;  
  151.     } 
  152.  
  153.     if(Fumbling) clumsy = TRUE;
  154.  
  155.     else if(uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25))
  156.         clumsy = TRUE;
  157. doit:
  158.     kludge("You kick %s.", mon_nam(mon));
  159.     if(!rn2(clumsy ? 3 : 4) && (clumsy || !bigmonst(mon->data)) && 
  160.        mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data) && 
  161.        mon->data->mlet != S_EEL && haseyes(mon->data) && mon->mcanmove && 
  162.        !mon->mstun && !mon->mconf && !mon->msleep &&
  163.        mon->data->mmove >= 12) {
  164.         if(!nohands(mon->data) && !rn2(martial() ? 5 : 3)) {
  165.             kludge("%s blocks your %skick.", Monnam(mon), 
  166.                 clumsy ? "clumsy " : "");
  167.             (void) passive(mon, FALSE, 1, TRUE);
  168.             return;
  169.         } else {
  170.             mnexto(mon);
  171.             if(mon->mx != x || mon->my != y) {
  172.                 pline("%s %s, %s evading your %skick.", 
  173.                 Blind ? "It" : Monnam(mon),
  174.                 (can_teleport(mon->data) ? "teleports" :
  175.                  is_floater(mon->data) ? "floats" :
  176.                  is_flyer(mon->data) ? "flutters" :
  177.                  nolimbs(mon->data) ? "slides" :
  178.                  "jumps"),
  179.                 clumsy ? "easily" : "nimbly",
  180.                 clumsy ? "clumsy " : "");
  181.             (void) passive(mon, FALSE, 1, TRUE);
  182.                 return;
  183.             } 
  184.         }
  185.     }
  186.     kickdmg(mon, clumsy);
  187. }
  188. #endif /* KICK */
  189.  
  190. /* return TRUE if caught, FALSE otherwise */
  191. boolean
  192. ghitm(mtmp, amount)
  193. register struct monst *mtmp;
  194. register long amount;
  195. {
  196.     if(!likes_gold(mtmp->data) && !mtmp->isshk 
  197. #if defined(ALTARS) && defined(THEOLOGY)
  198.         && !mtmp->ispriest
  199. #endif
  200.         ) 
  201.         wakeup(mtmp);
  202.     else {
  203.         mtmp->msleep = 0;
  204.         mtmp->meating = 0;
  205.         if(!rn2(4)) setmangry(mtmp); /* not always pleasing */
  206.         
  207.         /* greedy monsters catch gold */
  208.         kludge("%s catches the gold.", Monnam(mtmp));
  209.         mtmp->mgold += amount;
  210.         if (mtmp->isshk) {
  211.             long robbed = ESHK(mtmp)->robbed;
  212.  
  213.             if (robbed) {
  214.                 robbed -= amount;
  215.                 if (robbed < 0) robbed = 0;
  216.                 pline("The amount %scovers %s recent losses.",
  217.                     !robbed ? "" : "partially ", 
  218.                     ESHK(mtmp)->ismale ? "his" : "her");
  219.                 ESHK(mtmp)->robbed = robbed;
  220.                 if(!robbed)
  221.                     make_happy_shk(mtmp);
  222.             } else {
  223.                 if(mtmp->mpeaceful) {
  224.                     ESHK(mtmp)->credit += amount;
  225.                     You("have %ld zorkmid%s in credit.",
  226.                     ESHK(mtmp)->credit, 
  227.                     plur(ESHK(mtmp)->credit));
  228.                 } else verbalize("Thanks, scum!");
  229.             }
  230.         }
  231. #if defined(ALTARS) && defined(THEOLOGY)
  232.         else if(mtmp->ispriest) {
  233.             if(mtmp->mpeaceful)
  234.                 verbalize("Thank you for your contribution.");
  235.             else verbalize("Thanks, scum!");
  236.         }
  237. #endif
  238.         return(1);
  239.     }
  240.     return(0);
  241.  
  242. }
  243.  
  244. boolean
  245. bad_kick_throw_pos(x,y)
  246. xchar x,y;
  247. {
  248.     return(!accessible(x, y) || levl[x][y].typ == SDOOR);
  249. }
  250.  
  251. struct monst *
  252. ghit(ddx, ddy, range)
  253. register int ddx, ddy, range; 
  254. {
  255.     register struct monst *mtmp = (struct monst *) 0;
  256.  
  257.     bhitpos.x = u.ux;
  258.     bhitpos.y = u.uy;
  259.  
  260.     tmp_at(-1, GOLD_SYM);    /* open call */
  261.     tmp_at(-3, (int)AT_GLD);
  262.     while(range-- > 0) {
  263.         bhitpos.x += ddx;
  264.         bhitpos.y += ddy;
  265.         if(MON_AT(bhitpos.x, bhitpos.y)) {
  266.             mtmp = m_at(bhitpos.x,bhitpos.y);
  267.             tmp_at(-1, -1); /* close call */
  268.             return(mtmp);
  269.         }
  270.         /* stop on a zorkmid */
  271.         if(levl[bhitpos.x][bhitpos.y].gmask ||
  272.                      OBJ_AT(bhitpos.x, bhitpos.y)) {
  273.             tmp_at(-1, -1); /* close call */
  274.             return (struct monst *)0;
  275.         }
  276.         if(bad_kick_throw_pos(bhitpos.x,bhitpos.y)) {
  277.             bhitpos.x -= ddx;
  278.             bhitpos.y -= ddy;
  279.             break;
  280.         }
  281.         tmp_at(bhitpos.x, bhitpos.y);
  282.     }
  283.     tmp_at(-1, -1);
  284.     return(struct monst *)0;
  285. }
  286.  
  287. #ifdef KICK
  288. static int
  289. kick_object(x, y)
  290. int x, y;
  291. {
  292.     int range, odx, ody, cnt = 0;
  293.     register struct monst *mon;
  294.     struct gold *gold;
  295.     register struct obj *otmp;
  296.     boolean costly = FALSE;
  297.  
  298.     /* if a pile, the "top" object gets kicked */
  299.     for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
  300.         if(!otmp->cobj) {
  301.             cnt++;
  302.             if(cnt == 1) kickobj = otmp;
  303.         }
  304.  
  305.     /* range < 2 means the object will not move.    */
  306.     /* maybe dexterity should also figure here.     */
  307.     if(cnt) range = (int)((ACURR(A_STR) > 18 ? 20 : 
  308.                 ACURR(A_STR))/2 - kickobj->owt/4);
  309.     else range = rnd((int)ACURR(A_STR));
  310.  
  311.     if(martial()) range = range + rnd(3);
  312.     if(range < 1) range = 1; /* safety... */
  313.  
  314.     /* see if the object has a place to move into */
  315.     odx = x + u.dx;
  316.     ody = y + u.dy;
  317.     if(bad_kick_throw_pos(odx,ody))
  318.         range = 1;
  319.  
  320.     if(Fumbling && !rn2(3)) {
  321.         Your("clumsy kick missed.");
  322.         return(1);
  323.     }
  324.  
  325.     if(!cnt && levl[x][y].gmask) {
  326.         long zm;
  327.         gold = g_at(x, y);
  328.         zm = gold->amount;
  329.         if(IS_ROCK(levl[x][y].typ)) {
  330.             if ((!martial() && rn2(20) > ACURR(A_DEX))
  331. #ifdef POLYSELF
  332.                 || IS_ROCK(levl[u.ux][u.uy].typ)
  333. #endif
  334.                                 ) {
  335.                 pline("%s doesn't come loose.",
  336.                     Blind ? "It" : "The gold");
  337.                 return(!rn2(3) || martial());
  338.             }
  339.             pline("%s comes loose.", Blind ? "It" : "The gold");
  340.             freegold(gold);
  341.             newsym(x, y);
  342.             mkgold(zm, u.ux, u.uy);
  343.             if (Invisible
  344. #ifdef POLYSELF
  345.                     && !u.uundetected
  346. #endif
  347.                         ) newsym(u.ux, u.uy);
  348.             return(1);
  349.         }
  350.         if(range < 2 || zm > 300L) /* arbitrary */
  351.             return(0);
  352.         freegold(gold);
  353.         newsym(x, y);
  354.         if(mon = ghit(u.dx, u.dy, range)) {
  355.             setmangry(mon); /* not a means for payment to shk */
  356.             if(ghitm(mon, zm)) /* was it caught? */
  357.                 return(1);
  358.         }
  359.         mkgold(zm, bhitpos.x, bhitpos.y);
  360.         if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
  361.         return(1);
  362.     }
  363.  
  364.     /* cnt should always be >= 1 here (meaning kickobj is set) due to
  365.      * conditions of call */
  366.     if(!cnt || kickobj->otyp == BOULDER
  367.             || kickobj == uball || kickobj == uchain)
  368.         return(0);
  369.  
  370.     /* a box gets a chance of breaking open here */
  371.     if(Is_box(kickobj)) {
  372.         boolean otrp = kickobj->otrapped;
  373.  
  374.         if (!kickobj->olocked && (!rn2(3) ||
  375.                     (martial() && !rn2(2)))) {
  376.             pline("The lid slams open, then falls shut.");
  377.             if(otrp) (void) chest_trap(kickobj, LEG);
  378.             return(1);
  379.         } else if (kickobj->olocked && 
  380.                 (!rn2(5) || (martial() && !rn2(2)))) {
  381.             You("break open the lock!");
  382.             kickobj->olocked = 0;
  383.                 if(otrp) (void) chest_trap(kickobj, LEG);
  384.             return(1);
  385.         }
  386.         /* let it fall through to the next cases... */
  387.     }
  388.  
  389.     if(Levitation && !rn2(3)) {
  390.         You("miss."); /* do not identify the object */
  391.         return(1);
  392.     }
  393.  
  394.     /* fragile objects should not be kicked */
  395.     if (breaks(kickobj, FALSE)) return(1);
  396.  
  397.     costly = costly_spot(x, y);
  398.  
  399.     /* potions get a chance of breaking here */
  400.     if(kickobj->olet == POTION_SYM) {
  401.         if(rn2(2)) {
  402.             You("smash %s %s!",
  403.                 kickobj->quan==1 ? "the" : "a", xname(kickobj));
  404.             potionbreathe(kickobj);
  405.             useupf(kickobj);
  406.             return(1);
  407.         }
  408.     }
  409.  
  410.     if(IS_ROCK(levl[x][y].typ)) {
  411.         if ((!martial() && rn2(20) > ACURR(A_DEX))
  412. #ifdef POLYSELF
  413.                 || IS_ROCK(levl[u.ux][u.uy].typ)
  414. #endif
  415.                                 ) {
  416.             if (Blind) pline("It doesn't come loose.");
  417.             else pline("The %s do%sn't come loose.",
  418.                 distant_name(kickobj, xname),
  419.                 (kickobj->quan==1) ? "es" : "");
  420.             return(!rn2(3) || martial());
  421.         }
  422.         if (Blind) pline("It comes loose.");
  423.         else pline("The %s come%s loose.", distant_name(kickobj, xname),
  424.             (kickobj->quan==1) ? "s" : "");
  425.         move_object(kickobj, u.ux, u.uy);
  426.         newsym(x, y);
  427.         stackobj(kickobj);
  428.         if (Invisible
  429. #ifdef POLYSELF
  430.                 && !u.uundetected
  431. #endif
  432.                         ) newsym(u.ux, u.uy);
  433.         if (costly && !costly_spot(u.ux, u.uy))
  434.             addtobill(kickobj, FALSE);
  435.         return(1);
  436.     }
  437.  
  438.     /* too heavy to move. make sure not to call bhit  */
  439.     /* in this function when range < 2 (a display bug */
  440.     /* results otherwise).                */
  441.     if(range <= 2) {
  442.         if(Is_box(kickobj)) pline("THUD!");
  443.         else pline("Thump!");
  444.         if(!rn2(3) || martial()) return(1);
  445.         return(0);
  446.     }
  447.  
  448.     if (kickobj->quan > 1) (void) splitobj(kickobj, 1);
  449.  
  450.     /* Needed to fool bhit's display-cleanup to show immediately    */
  451.     /* the next object in the pile.  We know here that the object    */
  452.     /* will move, so there is no need to worry about the location,    */
  453.     /* which merely needs to be something other than ox, oy.    */
  454.     move_object(kickobj, u.ux, u.uy);
  455.     if(cnt == 1 && !MON_AT(x, y))
  456.         newsym(x, y);
  457.  
  458.     mon = bhit(u.dx, u.dy, range, kickobj->olet,
  459.             (int (*)()) 0, (int (*)()) 0, kickobj);
  460.     freeobj(kickobj);
  461.     if(mon) {
  462. # ifdef WORM
  463.         if (mon->mx != bhitpos.x || mon->my != bhitpos.y)
  464.             notonhead = TRUE;
  465. # endif
  466.         /* awake monster if sleeping */
  467.         wakeup(mon);
  468.         if(thitmonst(mon, kickobj)) return(1);
  469.     }
  470.     if(costly && !costly_spot(bhitpos.x,bhitpos.y))
  471.         addtobill(kickobj, FALSE);
  472.     move_object(kickobj, bhitpos.x, bhitpos.y);
  473.     kickobj->nobj = fobj;
  474.     fobj = kickobj;
  475.     stackobj(kickobj);
  476.     if(!MON_AT(kickobj->ox, kickobj->oy))
  477.         newsym(kickobj->ox, kickobj->oy);
  478.     return(1);
  479. }
  480.  
  481. static char *
  482. kickstr() {
  483.     static char NEARDATA buf[BUFSIZ];
  484.  
  485.     if (kickobj) Sprintf(buf, "kicking %s", doname(kickobj));
  486.     else if (IS_STWALL(maploc->typ)) Strcpy(buf, "kicking a wall");
  487.     else if (IS_ROCK(maploc->typ)) Strcpy(buf, "kicking a rock");
  488. #ifdef THRONES
  489.     else if (IS_THRONE(maploc->typ)) Strcpy(buf, "kicking a throne");
  490. #endif
  491. #ifdef SINKS
  492.     else if (IS_SINK(maploc->typ)) Strcpy(buf, "kicking a sink");
  493. #endif
  494. #ifdef ALTARS
  495.     else if (IS_ALTAR(maploc->typ)) Strcpy(buf, "kicking an altar");
  496. #endif
  497. #ifdef STRONGHOLD
  498.     else if (IS_DRAWBRIDGE(maploc->typ))
  499.         Strcpy(buf, "kicking the drawbridge");
  500. #endif
  501.     else {
  502.         switch (maploc->typ) {
  503.         case STAIRS:    
  504.             Strcpy(buf, "kicking the stairs");
  505.             break;
  506. #ifdef STRONGHOLD
  507.         case LADDER:
  508.             Strcpy(buf, "kicking a ladder");
  509.             break;
  510. #endif
  511.         }
  512.     }
  513.  
  514.     return buf;
  515. }
  516. #endif /* KICK */
  517.  
  518. int
  519. dokick() {
  520.         register int x, y;
  521.     register int avrg_attrib = (ACURR(A_STR)+ACURR(A_DEX)+ACURR(A_CON))/3;
  522.  
  523. #ifdef POLYSELF
  524.     if(nolimbs(uasmon)) {
  525.         You("have no legs to kick with.");
  526.         return(0);
  527.     }
  528.     if(verysmall(uasmon)) {
  529.         You("are too small to do any kicking.");
  530.         return(0);
  531.     }
  532. #endif
  533.     if(Wounded_legs) {
  534.         Your("%s %s in no shape for kicking.",
  535.               ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES)
  536.             ? makeplural(body_part(LEG)) : body_part(LEG),
  537.               ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES) ? "are" : "is");
  538.         return(0);
  539.     }
  540.  
  541.     if(inv_weight() > 0) {
  542.         Your("load is too heavy to balance yourself for a kick.");
  543.         return(0);
  544.     }
  545.  
  546.         if(u.utrap) {
  547.         switch (u.utraptype) {
  548.             case TT_PIT:
  549.             pline("There's nothing to kick down here.");
  550.             case TT_WEB:
  551.             case TT_BEARTRAP:
  552.             You("can't move your %s!", body_part(LEG));
  553.         }
  554.         return(0);
  555.     }
  556.  
  557.     if(!getdir(1)) return(0);
  558.     if(!u.dx && !u.dy) return(0);
  559.  
  560.     x = u.ux + u.dx;
  561.     y = u.uy + u.dy;
  562.  
  563.     if(u.uswallow) {
  564.         switch(rn2(3)) {
  565.         case 0:  You("can't move your %s!", body_part(LEG));
  566.              break;
  567.         case 1:  if (is_animal(u.ustuck->data)) {
  568.                  pline("%s burps loudly.", Monnam(u.ustuck)); 
  569.                        break; 
  570.                          }
  571.         default: Your("feeble kick has no effect."); break;
  572.         }
  573.         return(1);
  574.     }
  575.  
  576.     wake_nearby();
  577.     u_wipe_engr(2);
  578.  
  579.     maploc = &levl[x][y];
  580.  
  581. #ifdef KICK
  582.     /* The next four main loops should stay in */
  583.     /* their present order: monsters, objects, */
  584.     /* non-doors, doors.               */ 
  585.  
  586.     if(MON_AT(x, y)) {
  587.         kick_monster(x, y);
  588.         return(1);
  589.     }
  590.  
  591.     kickobj = (struct obj *)0;
  592.     if((OBJ_AT(x, y) || maploc->gmask) && !Levitation) {
  593.         if(kick_object(x, y)) return(1);
  594.         else goto ouch;
  595.     }
  596.  
  597.     if(!IS_DOOR(maploc->typ)) {
  598.         if(maploc->typ == SDOOR) {
  599.             if(rn2(30) < avrg_attrib) { 
  600.             pline("Crash!  You kick open a secret door!");
  601.             maploc->typ = DOOR;
  602.             if(maploc->doormask & D_TRAPPED) {
  603.                 b_trapped("door");
  604.                 maploc->doormask = D_NODOOR;
  605.             } else
  606.                 maploc->doormask = D_ISOPEN;
  607.             mnewsym(x,y);
  608.             prl(x,y);
  609.             return(1);
  610.             } else goto ouch;
  611.         }
  612.         if(maploc->typ == SCORR) {
  613.             if(rn2(30) < avrg_attrib) { 
  614.             pline("Crash!  You kick open a secret passage!");
  615.             maploc->typ = CORR;
  616.             mnewsym(x,y);
  617.             prl(x,y);
  618.             return(1);
  619.             } else goto ouch;
  620.         }
  621. # ifdef THRONES
  622.         if(IS_THRONE(maploc->typ)) {
  623.             register int i;
  624.             if((Luck < 0 || maploc->doormask) && !rn2(3)) {
  625.             pline("CRASH!  You destroy the throne.");
  626.             maploc->typ = ROOM;
  627.             maploc->doormask = 0; /* don't leave loose ends.. */
  628.             mkgold((long)rnd(200), x, y);
  629.             prl(x, y);
  630.             return(1);
  631.             } else if(Luck > 0 && !rn2(3) && !maploc->looted) {
  632.             You("kick loose some ornamental coins and gems!");
  633.             mkgold((300L+(long)rn2(201)), x, y);
  634.             i = Luck + 1;
  635.             if(i > 6) i = 6;
  636.             while(i--) (void) mkobj_at(GEM_SYM, x, y, TRUE);
  637.             prl(x, y);
  638.             /* prevent endless milking */
  639.             maploc->looted = T_LOOTED;
  640.             return(1);
  641.             } else if (!rn2(4)) {
  642.             fall_through(FALSE);
  643.             return(1);
  644.             }
  645.             goto ouch;
  646.         }
  647. # endif
  648. # ifdef ALTARS
  649.         if(IS_ALTAR(maploc->typ)) {
  650.             You("kick the altar.");
  651.             if(!rn2(3)) goto ouch; 
  652. #  ifdef THEOLOGY
  653.             altar_wrath(x, y);
  654. #  endif
  655.             return(1);
  656.         }
  657. # endif
  658. # ifdef SINKS
  659.         if(IS_SINK(maploc->typ)) {
  660.             if(rn2(5)) {
  661.             if(flags.soundok)
  662.                 pline("Klunk!  The pipes vibrate noisily.");
  663.             else pline("Klunk!");
  664.                 return(1);
  665.             } else if(!rn2(3) &&
  666.                   !(mons[PM_BLACK_PUDDING].geno & G_GENOD)) {
  667.             pline("A %s ooze gushes up from the drain!",
  668.                   Hallucination ? hcolor() : black);
  669.             pmon(makemon(&mons[PM_BLACK_PUDDING], x, y));
  670.             return(1);
  671. #  ifdef INFERNO
  672.             } else if(!rn2(3) &&
  673. #   ifndef POLYSELF
  674.                   poly_gender() != 2 &&
  675. #   endif
  676.                   !(mons[poly_gender() == 1 ? PM_INCUBUS : PM_SUCCUBUS].geno & G_GENOD)) {
  677.             /* can't resist... */
  678.             pline("The dish washer returns!");
  679.             pmon(makemon(&mons[poly_gender() == 1 ? PM_INCUBUS : PM_SUCCUBUS], x, y));
  680.             return(1);
  681. #  endif
  682.             } else if(!rn2(3)) {
  683.             pline("Flupp!  Muddy waste pops up from the drain.");
  684.             if(!maploc->looted) { /* only once per sink */
  685.                 if(!Blind) 
  686.                 You("see a ring shining in its midst.");
  687.                 (void) mkobj_at(RING_SYM, x, y, TRUE);
  688.                 prl(x, y);
  689.                 maploc->looted = T_LOOTED;
  690.             }
  691.             return(1);
  692.             }
  693.             goto ouch;
  694.         }
  695. # endif
  696.         if(maploc->typ == STAIRS 
  697. # ifdef STRONGHOLD
  698.                     || maploc->typ == LADDER
  699. # endif
  700.           ) goto ouch;
  701.         if(IS_STWALL(maploc->typ)) {
  702. ouch:
  703.             pline("Ouch!  That hurts!");
  704.             if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
  705.             losehp(rnd(ACURR(A_CON) > 15 ? 3 : 5), kickstr(),
  706.             KILLED_BY);
  707.             return(1);
  708.         }
  709. # ifdef STRONGHOLD
  710.         if (is_drawbridge_wall(x,y) >= 0) {
  711.             pline("The drawbridge is unaffected.");
  712.             return(1);
  713.         }
  714. # endif
  715.         goto dumb;
  716.     }
  717. #endif /* KICK */
  718.  
  719.     if(maploc->doormask == D_ISOPEN ||
  720.        maploc->doormask == D_BROKEN ||
  721.        maploc->doormask == D_NODOOR) {
  722. #ifdef KICK
  723. dumb:
  724. #endif
  725.         if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) {
  726.             You("kick at empty space.");
  727.         } else {
  728.             pline("Dumb move!  You strain a muscle.");
  729.             set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
  730.         }
  731.         return(0);
  732.     }
  733.  
  734.     /* door is known to be CLOSED or LOCKED */
  735.     if(rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX))) {
  736.         /* break the door */
  737.         if(maploc->doormask & D_TRAPPED) {
  738.             pline("As you kick the door, it explodes!");
  739.             b_trapped("door");
  740.             maploc->doormask = D_NODOOR;
  741.         } else if(ACURR(A_STR) > 18 && !rn2(5) && !in_shop(x, y)) {
  742.             pline("As you kick the door, it shatters to pieces!");
  743.             maploc->doormask = D_NODOOR;
  744.         } else {
  745.             pline("As you kick the door, it crashes open!");
  746.             maploc->doormask = D_BROKEN;
  747.             if(in_shop(x, y))
  748.             pay_for_door(x, y, "break");
  749.         }
  750.         mnewsym(x,y);
  751.         prl(x,y);
  752.     } else    pline("WHAMMM!!!");
  753.  
  754.     return(1);
  755. }
  756.